package com.tjetc.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tjetc.entity.CityDetail;
import com.tjetc.entity.Food;
import com.tjetc.entity.Spot;
import com.tjetc.entity.Travelogue;
import com.tjetc.service.CityDetailService;
import com.tjetc.service.FoodService;
import com.tjetc.service.SpotService;
import com.tjetc.service.TravelogueService;
import com.tjetc.service.UserService;
import com.tjetc.common.JsonResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 城市详情控制器
 */
@RestController
@RequestMapping("/cityDetail")
@Tag(name = "城市详情管理", description = "城市详情的CRUD操作")
public class CityDetailController {

    @Autowired
    private CityDetailService cityDetailService;
    
    @Autowired
    private SpotService spotService;
    
    @Autowired
    private FoodService foodService;
    
    @Autowired
    private TravelogueService travelogueService;
    
    @Autowired
    private UserService userService;

    /**
     * 根据ID查询城市详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "根据ID查询城市详情")
    public JsonResult<CityDetail> getById(@Parameter(description = "城市ID", required = true) @PathVariable("id") Long id) {
        CityDetail cityDetail = cityDetailService.getCityDetailById(id);
        if (cityDetail != null) {
            return JsonResult.success(cityDetail);
        } else {
            return JsonResult.fail("城市不存在");
        }
    }

    /**
     * 新增城市
     */
    @PostMapping
    @Operation(summary = "新增城市")
    public JsonResult<Boolean> add(@Parameter(description = "城市信息", required = true) @RequestBody CityDetail cityDetail) {
        boolean result = cityDetailService.addCityDetail(cityDetail);
        if (result) {
            return JsonResult.success(true);
        } else {
            return JsonResult.fail("新增城市失败");
        }
    }

    /**
     * 更新城市
     */
    @PutMapping
    @Operation(summary = "更新城市")
    public JsonResult<Boolean> update(@Parameter(description = "城市信息", required = true) @RequestBody CityDetail cityDetail) {
        if (cityDetail.getCityId() == null) {
            return JsonResult.fail("城市ID不能为空");
        }
        boolean result = cityDetailService.updateCityDetail(cityDetail);
        if (result) {
            return JsonResult.success(true);
        } else {
            return JsonResult.fail("更新城市失败");
        }
    }

    /**
     * 删除城市
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除城市")
    public JsonResult<Boolean> delete(@Parameter(description = "城市ID", required = true) @PathVariable("id") Long id) {
        boolean result = cityDetailService.deleteCityDetail(id);
        if (result) {
            return JsonResult.success(true);
        } else {
            return JsonResult.fail("删除城市失败");
        }
    }

    /**
     * 根据城市名称模糊查询
     */
    @GetMapping("/search/name")
    @Operation(summary = "根据城市名称模糊查询")
    public JsonResult<List<CityDetail>> getByName(
            @Parameter(description = "城市名称", required = true) @RequestParam String name) {
        List<CityDetail> cities = cityDetailService.getCityDetailsByName(name);
        return JsonResult.success(cities);
    }

    /**
     * 查询评分大于等于指定分数的城市
     */
    @GetMapping("/search/score")
    @Operation(summary = "查询评分大于等于指定分数的城市")
    public JsonResult<List<CityDetail>> getByScore(
            @Parameter(description = "最低评分", required = true) @RequestParam Double score) {
        List<CityDetail> cities = cityDetailService.getCityDetailsByScoreGreaterThan(score);
        return JsonResult.success(cities);
    }

    /**
     * 根据最佳旅游季节查询城市
     */
    @GetMapping("/search/season")
    @Operation(summary = "根据最佳旅游季节查询城市")
    public JsonResult<List<CityDetail>> getBySeason(
            @Parameter(description = "季节关键词", required = true) @RequestParam String season) {
        List<CityDetail> cities = cityDetailService.getCityDetailsBySeason(season);
        return JsonResult.success(cities);
    }

    /**
     * 分页查询城市信息
     */
    @GetMapping("/page")
    @Operation(summary = "分页查询城市信息")
    public JsonResult<IPage<CityDetail>> getPage(
            @Parameter(description = "页码", required = true) @RequestParam(defaultValue = "1") long current,
            @Parameter(description = "每页大小", required = true) @RequestParam(defaultValue = "10") long size,
            @Parameter(description = "城市名称") @RequestParam(required = false) String name) {
        Page<CityDetail> page = new Page<>(current, size);
        IPage<CityDetail> pageResult = cityDetailService.getCityDetailPage(page, name);
        return JsonResult.success(pageResult);
    }

    /**
     * 根据城市code查询城市详情
     */
    @GetMapping("/code/{code}")
    @Operation(summary = "根据城市code查询城市详情")
    public JsonResult<CityDetail> getByCode(@Parameter(description = "城市code", required = true) @PathVariable("code") Long code) {
        CityDetail cityDetail = cityDetailService.getCityDetailByCode(code);
        if (cityDetail != null) {
            return JsonResult.success(cityDetail);
        } else {
            return JsonResult.fail("城市不存在");
        }
    }


    /**
     * 根据城市code查询该城市热度前N个景点
     */
    @GetMapping("/spots/top/{code}/{limit}")
    @Operation(summary = "根据城市code查询热度前N个景点")
    public JsonResult getTopSpotsByCityCode(
            @Parameter(description = "城市code", required = true) @PathVariable("code") Long code,
            @Parameter(description = "查询数量限制", required = true) @PathVariable("limit") int limit) {
        return spotService.getTopSpotsByCity(code, limit);
    }
    
    /**
     * 获取城市所有景点（带分页和筛选）
     */
    @GetMapping("/spots/{code}")
    @Operation(summary = "获取城市所有景点（带分页和筛选）")
    public JsonResult getSpotsWithPaginationAndFilters(
            @Parameter(description = "城市代码", required = true) @PathVariable("code") Long cityCode,
            @Parameter(description = "页码") @RequestParam(required = false, defaultValue = "1") Integer page,
            @Parameter(description = "每页显示数量") @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @Parameter(description = "景点类型筛选") @RequestParam(required = false) String type,
            @Parameter(description = "价格范围筛选：free, low, medium, high") @RequestParam(required = false) String priceRange,
            @Parameter(description = "评分筛选：3, 4, 5") @RequestParam(required = false) Integer rating,
            @Parameter(description = "排序字段：name, price, rating") @RequestParam(required = false) String sortKey,
            @Parameter(description = "排序方向：asc, desc") @RequestParam(required = false) String sortDirection
    ) {
        return spotService.getSpotsByCityWithFilters(
                cityCode, page, pageSize, type, priceRange, rating, sortKey, sortDirection
        );
    }
    
    /**
     * 获取城市美食
     */
    @GetMapping("/foods/{cityId}")
    @Operation(summary = "获取城市美食")
    public JsonResult getFoodsByCityId(
            @Parameter(description = "城市ID", required = true) @PathVariable Long cityId,
            @Parameter(description = "美食分类") @RequestParam(required = false) String category) {
        
        List<Food> foodList;
        if (category != null && !category.isEmpty()) {
            // 如果指定了分类，则查询指定分类的美食
            foodList = foodService.getFoodsByCityIdAndCategory(cityId, category);
        } else {
            // 否则查询所有分类的美食
            foodList = foodService.getFoodsByCityId(cityId);
        }
        
        // 获取所有分类
        List<String> categories = foodService.getFoodsByCityId(cityId).stream()
            .map(Food::getCategory)
            .distinct()
            .collect(Collectors.toList());
            
        // 构建响应数据
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("data", foodList);
        resultMap.put("total", foodList.size());
        resultMap.put("categories", categories);
        
        return JsonResult.success(resultMap);
    }
    
    /**
     * 获取城市所有景点的游记
     */
    @GetMapping("/travelogues/{cityCode}")
    @Operation(summary = "获取城市所有景点的游记", description = "根据城市编码获取该城市所有景点的游记信息，包含作者信息")
    public JsonResult getCitySpotTravelogues(
            @Parameter(description = "城市编码", required = true) @PathVariable("cityCode") Long cityCode,
            @Parameter(description = "是否只查询精选游记") @RequestParam(required = false) Boolean isFeatured,
            @Parameter(description = "是否只查询编辑推荐") @RequestParam(required = false) Boolean isEditor,
            @Parameter(description = "按热度排序：view, like, comment") @RequestParam(required = false, defaultValue = "view") String sortBy) {
        
        // 1. 获取该城市的所有景点
        JsonResult spotResult = spotService.getSpotByCity(cityCode);
        if (spotResult.getState() != 0 || spotResult.getData() == null) {
            return JsonResult.fail("未找到该城市的景点信息");
        }
        
        List<Spot> spots = (List<Spot>) spotResult.getData();
        if (spots.isEmpty()) {
            return JsonResult.success("该城市暂无景点", new ArrayList<>());
        }
        
        // 2. 收集景点ID
        List<Long> spotIds = spots.stream()
                .map(Spot::getSpotId)
                .collect(Collectors.toList());
        
        // 3. 构建查询参数，使用景点ID列表进行过滤
        Map<String, Object> params = new HashMap<>();
        params.put("spotIds", spotIds);  // 使用景点ID列表进行过滤
        params.put("isFeatured", isFeatured);
        params.put("isEditor", isEditor);
        params.put("sortBy", sortBy);
        params.put("includeUserInfo", true); // 添加参数指示需要包含用户信息
        
        // 4. 查询游记
        JsonResult travelogueResult = travelogueService.findByCitySpots(params);
        
        return travelogueResult;
    }
    
}

